<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
		<script src="js/jquery-1.10.2.min.js"></script>
	</head>

	<body>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
			}
			
			html,
			body {
				height: 100%;
				overflow: hidden;
			}
			
			.protagonist {
				width: 20px;
				height: 40px;
				background-color: #0085C8;
				position: absolute;
				left: 50%;
				bottom: 0;
				margin-left: -10px;
			}
			
			.stairs {
				width: 100px;
				height: 20px;
				background: #ff00ff;
				opacity: 0.5;
				position: absolute;
				left: 50%;
				bottom: 0;
				margin-left: -50px;
			}
			
			.wing {
				width: 100px;
				height: 50px;
				background-color: #004C1E;
				opacity: 0.5;
				position: absolute;
				margin-left: -50px;
			}
			
			.knapsack {
				width: 100px;
				height: 50px;
				background-color: #F16543;
				opacity: 0.5;
				position: absolute;
				margin-left: -50px;
			}
			input{
				position: absolute;
				z-index: 99;
			}
		</style>
		<!--<input id="range" type="range" value="0" min="-100" max="100" step="1" style="width: 200px;" />滑块模拟重力加速度-->
		<input id="range" type="range" value="50" min="0" max="100" step="1" style="width: 100%;" />滑块模拟x轴位子
		<div id="canvas-1">
			<div id="protagonist" class="protagonist"></div>
		</div>
		<script>
			$(function() {
				/*JQ自定义input事件*/
				var ie = !-[1, ];
				$.fn.input = function(Fn) {
					if(ie) {
						$(this).on('propertychange', function() {
							Fn.apply(this);
						})
					} else {
						$(this).on('input', function() {
							Fn.apply(this);
						})
					}
				};
				/* */
				$('#range').input(function() { //模拟重力加速度
					Xt = this.value * winW * 0.01;
				});
				/* */

				var t0 = 0.018; //默认屏幕刷新时间

				var $P = $('#protagonist'); //人物
				var X0 = parseFloat($P.css('left')), //人物初始位置x
					Y0 = parseFloat($P.css('bottom')); //人物初始位置y

				var Vy0 = 500, //初始y轴速度
					Vx0 = 0, //初始x轴速度
					ay = 600, //初始y轴加速度
					ax = 0; //初始x轴加速度

				var Xt = X0, //人物当前位置x
					Yt = Y0, //人物当前位置y
					Vyt = Vy0, //人物当前y轴速度
					Vxt = Vx0, //人物当前x轴速度
					ayt = ay, //人物当前y轴加速度
					axt = ax; //人物当前x轴加速度

				var ground = 0, //地面y轴位置
					winW = $(window).width(); //屏幕宽
				var endG = false; //是否结束
				var LocB = true; //是否运动
				var LocFn = function() { //人物运动函数
					if(LocB) {
						Vxt = Vxt + axt * t0;
						Vyt = Vyt - ayt * t0;
						/*//此处正式用时请解开
						Xt = Vxt * t0 + Xt;*/
						Yt = Vyt * t0 + Yt;
						$P.css({
							'left': Xt,
							'bottom': Yt,
						});
						if(Vyt <= 0 && Yt <= ground) {
							if(Yt > -10) {
								Vyt = Vy0;
							} else {
								endG = true;
								alert('哦噢，死了！');
							}
						};
						if(Xt > winW + 30) {
							Xt = -30
						};
						if(Xt < -30) {
							Xt = winW + 30
						}
					}
				};

				var $stair = $('<div class=stairs>'); //创建台阶

				/*var stairsL = [ //台阶位置数组
					[0.4, 100, 1],
					[0.5, 150, 2],
					[0.5, 300, 3],
					[0.5, 400, 4],
					[0.5, 450, 5],
					[0.5, 600, 6],
					[0.5, 700, 7],
					[0.5, 800, 8],
					[0.5, 900, 9],
					[0.8, 1000, 10],
				];*/
				var stairsL = [];
				for(var i = 0; i < 10; i++) { //渲染台阶
					stairsL[i] = [];
					stairsL[i][0] = Math.random();
					if(i == 0) {
						stairsL[i][1] = 50 + parseFloat(Math.random() * 50);
					} else {
						stairsL[i][1] = 50 + parseFloat(Math.random() * 50) + stairsL[i - 1][1];
					}
					stairsL[i][2] = i + 1;

					stairsL[i][0] = stairsL[i][0] * winW;
					$stair.clone().appendTo('#canvas-1').css({
						'left': stairsL[i][0],
						'bottom': stairsL[i][1]
					}).html('台阶' + stairsL[i][2]);
					$stairs = $('.stairs');
				};

				/* */
				var collideB = true; //登上台阶检测
				var onStageNumber = 0;
				var collideFn = function() { //登上台阶函数
					if(Vyt < 0 && collideB) {
						for(var i = 0; i < stairsL.length; i++) {
							if(Yt <= stairsL[i][1] + 10 && Yt - Vyt * t0 >= stairsL[i][1] + 10) {
								if(Xt >= stairsL[i][0] - 50 && Xt <= stairsL[i][0] + 50) {
									console.log('登上台阶' + stairsL[i][2]);
									onStageNumber = stairsL[i][2];
									Vyt = Vy0;
									if(Yt > 300) { //触发画布相对运动
										falldownB = true;
									}
								}
							}
						}
					}
				};
				/* */
				var winH = document.documentElement.clientHeight;
				/*翅膀*/
				var $wing = $('<div class=wing>');
				var wingLeft, wingBottm;
				var wingB = false;
				var wingE = false; //有无翅膀
				var wingFn = function() {
					if(wingB) {
						wingBottm = Math.random() * winH * 0.5 + winH * 0.4;
						var wingLeftNot = [];
						for(var i = 0; i < stairsL.length - 1; i++) {
							if(stairsL[i][1] >= wingBottm && stairsL[i][1] < wingBottm + 100) {
								wingLeftNot[0] = stairsL[i][0];
								wingLeftNot[1] = stairsL[i + 1][0];
								break;
							}
						}
						var coincide = 20, //翅膀可与台阶重合度
							notCoincide = 50 - coincide;
						var wingLeftM = function() {
							wingLeft = Math.random() * winW;
							if((wingLeft >= wingLeftNot[0] - notCoincide && wingLeft <= wingLeftNot[0] + notCoincide) || (wingLeft >= wingLeftNot[1] - notCoincide && wingLeft <= wingLeftNot[1] + notCoincide)) {
								wingLeftM();
							} else {
								//wingLeft = winW * 0.5; //手动设置的位子
								$wing.appendTo('#canvas-1').css({
									'bottom': wingBottm,
									'left': wingLeft
								}).html('翅膀');
								wingE = true;
							}
						}
						wingLeftM();
						wingB = false;
					}
				};
				var wingCollideB = true;
				var wingCollideFn = function() {
					if(wingCollideB && wingE) {
						//此处为碰撞的接触距离,可以根据实际效果调整
						if(Yt + 40 >= wingBottm && Yt <= wingBottm + 50) {
							//此处为碰撞的接触距离,可以根据实际效果调整
							if(Xt + 10 <= wingLeft + 50 && Xt - 10 >= wingLeft - 50) {
								console.log('碰撞到翅膀');
								$wing.remove(); //删除翅膀
								wingE = false;
								wingUpB = true; //打开翅膀飞升
								collideB = false; //关闭登上台阶检测
								wingCollideB = false; //关闭翅膀碰撞检测
								knapsackCollideB = false; //关闭背包检测
								LocB = false; //关闭人物主动运动
							}
						}
					}
				};

				var wingUpB = false,
					wingUpC = 0,
					UpC = 5;
				var wingUpFn = function() { //翅膀飞升
					if(wingUpB) {
						//ground -= 5;
						for(var i = 0; i < stairsL.length; i++) {
							stairsL[i][1] -= 5;
						}
						$stairs.css('bottom', '-=5');
						wingUpC++;

						wingBottm -= 5;
						$wing.css('bottom', '-=5');

						knapsackBottm -= 5;
						$knapsack.css('bottom', '-=5');

						if(wingUpC == 20 * UpC) {
							wingUpB = false;
							wingUpC = 0;
							for(var j = 0; j < UpC; j++) {
								falldown++;
								refreshFn();
							}
							collideB = true; //打开登上台阶检测
							wingCollideB = true; //打开翅膀碰撞检测
							knapsackCollideB = true; //打开背包检测
							LocB = true; //打开人物主动运动
						}
					}
				}
				/*翅膀结束*/
				/*背包*/
				var $knapsack = $('<div class=knapsack>');
				var knapsackLeft, knapsackBottm;
				var knapsackB = false;
				var knapsackE = false; //有无背包
				var knapsackFn = function() {
					if(knapsackB) {
						knapsackBottm = Math.random() * winH * 0.5 + winH * 0.4;
						var knapsackLeftNot = [];
						for(var i = 0; i < stairsL.length - 1; i++) {
							if(stairsL[i][1] >= knapsackBottm && stairsL[i][1] < knapsackBottm + 100) {
								knapsackLeftNot[0] = stairsL[i][0];
								knapsackLeftNot[1] = stairsL[i + 1][0];
								break;
							}
						}
						var coincide = 30, //背包可与台阶重合度
							notCoincide = 50 - coincide;
						var knapsackLeftM = function() {
							knapsackLeft = Math.random() * winW;
							if((knapsackLeft >= knapsackLeftNot[0] - notCoincide && knapsackLeft <= knapsackLeftNot[0] + notCoincide) || (knapsackLeft >= knapsackLeftNot[1] - notCoincide && knapsackLeft <= knapsackLeftNot[1] + notCoincide)) {
								knapsackLeftM();
							} else {
								//knapsackLeft = winW * 0.5; //手动设置的位置
								$knapsack.appendTo('#canvas-1').css({
									'bottom': knapsackBottm,
									'left': knapsackLeft
								}).html('背包');
								knapsackE = true;
							}
						}
						knapsackLeftM();
						knapsackB = false;
					}
				};
				var knapsackCollideB = true;
				var knapsackCollideFn = function() {
					if(knapsackCollideB && knapsackE) {
						//此处为碰撞的接触距离,可以根据实际效果调整
						if(Yt + 40 >= knapsackBottm && Yt <= knapsackBottm + 50) {
							//此处为碰撞的接触距离,可以根据实际效果调整
							if(Xt + 10 <= knapsackLeft + 50 && Xt - 10 >= knapsackLeft - 50) {
								console.log('碰撞到背包');
								$knapsack.remove(); //删除背包
								knapsackE = false;
								knapsackDownB = true; //打开背包下跌
								collideB = false; //关闭登上台阶检测
								wingCollideB = false; //关闭翅膀碰撞检测
								knapsackCollideB = false; //关闭背包检测
								LocB = false; //关闭人物主动运动
							}
						}
					}
				};

				var knapsackDownB = false,
					knapsackDownC = 0,
					downC = 3;
				var knapsackDownFn = function() { //背包下跌
					if(knapsackDownB) {
						//ground += 5;
						for(var i = 0; i < stairsL.length; i++) {
							stairsL[i][1] += 5;
						}

						$stairs.css('bottom', '+=5');
						knapsackDownC++;

						wingBottm += 5;
						$wing.css('bottom', '+=5');

						knapsackBottm += 5;
						$knapsack.css('bottom', '+=5');

						wingCollideB = false; //关闭翅膀检测
						if(knapsackDownC == 20 * downC) {
							knapsackDownB = false;
							knapsackDownC = 0;
							for(var j = 0; j < downC; j++) {
								falldown--;
								refresh2Fn();
							}
							collideB = true; //打开登上台阶检测
							wingCollideB = true; //打开翅膀碰撞检测
							knapsackCollideB = true; //打开背包检测
							LocB = true; //打开人物主动运动
						}
					}
				}
				/*背包结束*/
				/* */
				var falldownB = false, //触发画布相对运动布尔值
					falldownC = 0, //计数器
					falldown = 0; //下降台阶数
				var $stairs = $('.stairs'); //所有台阶
				var falldownFn = function() { //画布相对运动函数
					if(falldownB) {
						ground -= 5;
						Yt -= 5;
						$P.css({
							'bottom': Yt,
						})
						for(var i = 0; i < stairsL.length; i++) {
							stairsL[i][1] -= 5;
						}
						$stairs.css('bottom', '-=5');
						falldownC++;

						wingBottm -= 5;
						$wing.css('bottom', '-=5');

						knapsackBottm -= 5;
						$knapsack.css('bottom', '-=5');

						if(falldownC == 20) {
							falldownB = false;
							falldownC = 0;
							falldown++;
							refreshFn();
						}
					}
				};
				/* */
				var refreshFn = function() { //更新台阶
					if(stairsL[0][1] < -10) {
						stairsL.shift();
						stairsL.push([Math.random(), stairsL[stairsL.length - 1][1] + 50 + parseInt(100 * Math.random()), stairsL[stairsL.length - 1][2] + 1]);
						stairsL[stairsL.length - 1][0] = stairsL[stairsL.length - 1][0] * winW;
						$stairs.eq(0).remove();
						$stair.clone().appendTo('#canvas-1').css({
							'left': stairsL[stairsL.length - 1][0],
							'bottom': stairsL[stairsL.length - 1][1]
						}).html('台阶' + stairsL[stairsL.length - 1][2]);
						$stairs = $('.stairs');
					}
				};
				var refresh2Fn = function() { //向下更新台阶
					var stairsLlen = stairsL.length;
					if(stairsL[stairsLlen - 1][1] > winH + 20) {
						stairsL.pop();
						stairsL.unshift([Math.random(), stairsL[0][1] - 50 - parseInt(100 * Math.random()), stairsL[0][2] - 1]);
						stairsL[0][0] = stairsL[0][0] * winW;
						$stairs.eq(-1).remove();
						$stair.clone().prependTo('#canvas-1').css({
							'left': stairsL[0][0],
							'bottom': stairsL[0][1]
						}).html('台阶' + stairsL[0][2]);
						$stairs = $('.stairs');
					}
				};

				window.requestAnimFrame = (function() {
					return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
						window.setTimeout(callback, 1000 / 60);
					};
				})();

				setInterval(function() {
					knapsackB = true;
				}, 4000);

				setInterval(function() {
					wingB = true;
				}, 5000);

				var render = function() {
					LocFn();
					collideFn();
					falldownFn();
					wingFn();
					wingCollideFn();
					wingUpFn();
					knapsackFn();
					knapsackCollideFn();
					knapsackDownFn();

					if(!endG) {
						window.requestAnimationFrame(render);
					}
				}; //调用render方法
				render();
			})
		</script>
	</body>

</html>